package com.zxy.supplier_system.server.service

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.convertValue
import com.zxy.supplier_system.server.entity.Employee
import com.zxy.supplier_system.server.entity.Notification
import com.zxy.supplier_system.server.repository.NotificationRepository
import org.springframework.scheduling.annotation.EnableScheduling
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.OffsetDateTime

@Service
@EnableScheduling
class NotificationService(
    private val notificationRepository: NotificationRepository,
    private val employeeService: EmployeeService,
    private val objectMapper: ObjectMapper,
) {

    companion object {
        const val NOTIFICATION_EXPIRED_MILLIS_SECONDS = 1000L * 60 * 60 * 24 * 7
    }

    @Transactional
    fun getNotifications(): List<Notification> {
        val notifications =
            notificationRepository.findAllByConsumedDateTimeIsNullAndReceiver(employeeService.getRequiredCurrentEmployee())
        for (notification in notifications) {
            notification.consumedDateTime = OffsetDateTime.now()
        }
        return this.notificationRepository.saveAll(notifications)
    }

    @Transactional
    fun pushNotification(type: Notification.Type, receiver: Employee, data: Any?) {
        this.notificationRepository.save(Notification().apply {
            this.type = type
            this.data = data?.let { objectMapper.convertValue(it) }
            this.receiver = receiver
        })
    }

    @Scheduled(fixedRate = NOTIFICATION_EXPIRED_MILLIS_SECONDS)
    @Transactional
    fun clearUnconsumedNotification() {
        this.notificationRepository.deleteByConsumedDateTimeBeforeOrConsumedDateTimeIsNull(
            OffsetDateTime.now().minusSeconds(
                NOTIFICATION_EXPIRED_MILLIS_SECONDS / 1000
            )
        )
    }


}
